package com.thread.pool.core.service.impl;

import com.thread.pool.core.common.executor.ThreadPoolManager;
import com.thread.pool.core.service.ThreadPoolService;
import com.thread.pool.domain.dto.ThreadPoolDataDto;
import com.thread.pool.domain.param.ThreadPoolParam;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.ConfigurableApplicationContext;
import org.springframework.stereotype.Service;

import java.util.concurrent.ThreadPoolExecutor;
import java.util.concurrent.TimeUnit;

/**
 * 动态修改线程池实现类
 * @author yangj
 */
@Service
public class ThreadPoolServiceImpl implements ThreadPoolService {

    @Autowired
    ThreadPoolManager threadPoolManager;

    /**
     * 根据参数重新设置线程池
     * @param dto
     */
    @Override
    public void reset(ThreadPoolParam dto) {
        threadPoolManager.reset(dto);
    }

    /**
     * 根据上下文容器重新设置线程池
     * 这种方式可以用来处理有配置中心的情况，可以监听配置中心数据的变化来刷新线程池
     * @param context
     */
    @Override
    public void resetWithContext(ConfigurableApplicationContext context) {
        threadPoolManager.reset(context);
    }

    /**
     * 获取线程池相关数据
     */
    @Override
    public ThreadPoolDataDto getExecutorStatus() {
        ThreadPoolExecutor executor = (ThreadPoolExecutor)threadPoolManager.getExecutorService();
        ThreadPoolDataDto threadPoolDataDto = ThreadPoolDataDto.build()
                .setCoreSize(executor.getCorePoolSize())
                .setKeepAlive(executor.getKeepAliveTime(TimeUnit.SECONDS))
                .setMaxSize(executor.getMaximumPoolSize())
                .setCallerRunsPolicy(executor.getRejectedExecutionHandler().getClass().getName())
                .setQueueSize(executor.getQueue().size())
                .setRemainingCapacity(executor.getQueue().remainingCapacity())
                .setCompletedTaskCount(executor.getCompletedTaskCount())
                .setLargestPoolSize(executor.getLargestPoolSize())
                .setTaskCount(executor.getTaskCount())
                .setActiveCount(executor.getActiveCount())
                .setPoolSize(executor.getPoolSize());
        return threadPoolDataDto;
    }
}
